package com.mobile.business.tree.impl;

import java.util.List;
import java.util.Map;

import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;

import com.mobile.business.BaseBusiness;
import com.mobile.business.tree.ITreeBaseBusiness;
import com.mobile.model.TreeBasePojo;
import com.mobile.tools.JsonHelp;

/**
 * 处理菜单的业务逻辑类
 * 
 * @author hf
 * 
 */
public class TreeBaseBusinessImpl extends BaseBusiness implements ITreeBaseBusiness {

	private final static String PARENT_ID = "parentId";
	private final static String SERIAL_NUMBER = "serialNumber";
	private final static String UNIQUE_CODE = "uniqueCode";
	
	
	public void saveSort(Map map,Class clazz) {
		// TODO Auto-generated method stub
		String point = (String)map.get("point");
		
		String dropNodeId = (String)map.get("dropNode");
		String targetNodeId = (String)map.get("target");
		
		if("append".equals(point)){
			this.saveAppend(dropNodeId, targetNodeId,clazz);
		}else if("above".equals(point)){
			this.saveAbove(dropNodeId, targetNodeId,clazz);
		}else if("below".equals(point)){
			this.saveBelow(dropNodeId, targetNodeId,clazz);
		}
	}
	public void saveSort(String jsonData,Class clazz) {
		// TODO Auto-generated method stub
		JsonHelp jsonHelp=new JsonHelp();
		Map map=jsonHelp.getJsonToMap(jsonData);
		this.saveSort(map,clazz);
	}
	/**
	 * 把放节点添加到放置于目标节点的前面
	 * @param dropNodeId		放节点id
	 * @param targetNodeId		目标节点id
	 */
	public void saveAbove(String dropNodeId, String targetNodeId,Class clazz) {
		// TODO Auto-generated method stub
		TreeBasePojo treeNodeTarget = (TreeBasePojo)this.baseDAO.get(clazz, targetNodeId);
		TreeBasePojo treeNodeDrop = (TreeBasePojo)this.baseDAO.get(clazz, dropNodeId);
		
		DetachedCriteria criteria = DetachedCriteria
				.forClass(clazz)
				.add(Restrictions.eq(this.PARENT_ID,treeNodeTarget.getParentId()))
				.add(Restrictions.le(this.SERIAL_NUMBER, treeNodeTarget.getSerialNumber()));
		
		List<TreeBasePojo> list=this.baseDAO.findByCriteria(criteria);
		
		Long l=(treeNodeTarget.getSerialNumber()==null?0:treeNodeTarget.getSerialNumber());
		
		
		treeNodeDrop.setSerialNumber(l);
		treeNodeDrop.setParentId(treeNodeTarget.getParentId());
		
		for(TreeBasePojo treeNode:list){
			treeNode.setSerialNumber(++l);
		}
		
		TreeBasePojo fatherTreeBasePojo = (TreeBasePojo)this.baseDAO.get(clazz, treeNodeTarget.getParentId());
		
		this.setIsLeafNode(fatherTreeBasePojo,clazz);
	}
	/**
	 * 把节点id为targetNodeId的的节点添加到节点Id为dropNodeId的节点中
	 * @param	dropNodeId		放的节点Id
	 * @param	targetNodeId	拖的目标节点Id
	 */
	public void saveAppend(String dropNodeId, String targetNodeId,Class clazz) {
		// TODO Auto-generated method stub
		TreeBasePojo treeNodeTarget = (TreeBasePojo)this.baseDAO.get(clazz, targetNodeId);
		TreeBasePojo treeNodeDrop = (TreeBasePojo)this.baseDAO.get(clazz, dropNodeId);
		
		Long serialNumber=Long.valueOf(this.getMaxSerialNumber(targetNodeId,clazz));
		
		treeNodeDrop.setSerialNumber(serialNumber+1);
		//设置放对象的节点为支节点
		treeNodeTarget.setIsLeafNode("0");
		
		TreeBasePojo fatherTreeBasePojo=(TreeBasePojo)this.baseDAO.get(clazz, treeNodeTarget.getParentId());
		treeNodeDrop.setParentId(treeNodeTarget.getParentId());		
		this.setIsLeafNode(fatherTreeBasePojo,clazz);
	}
	/**
	 * 把放节点添加到放置于目标节点的后面
	 * @param dropNodeId		放节点id
	 * @param targetNodeId		目标节点id
	 */
	public void saveBelow(String dropNodeId, String targetNodeId,Class clazz) {
		// TODO Auto-generated method stub
		TreeBasePojo treeNodeTarget = (TreeBasePojo)this.baseDAO.get(clazz, targetNodeId);
		TreeBasePojo treeNodeDrop = (TreeBasePojo)this.baseDAO.get(clazz, dropNodeId);
		Long serialNumber=Long.valueOf(this.getMaxSerialNumber(treeNodeTarget.getParentId(),clazz));
		
		treeNodeDrop.setParentId(treeNodeTarget.getParentId());
		treeNodeDrop.setSerialNumber(serialNumber+1);
		
		TreeBasePojo fatherTreeBasePojo=(TreeBasePojo)this.baseDAO.get(clazz, treeNodeTarget.getParentId());
		
		this.setIsLeafNode(fatherTreeBasePojo,clazz);
	}
	/**
	 * 根据此节点是否又子节点来设置isLeafNode属性
	 * @param treeNode	节点
	 */
	public void setIsLeafNode(TreeBasePojo treeNode,Class clazz){
		//TreeBasePojo treeNode = (TreeBasePojo)this.baseDAO.get(clazz, nodeId);

		if(!hasChildren(treeNode.getUniqueCode(),clazz)){
			treeNode.setIsLeafNode("1");
		}else{
			treeNode.setIsLeafNode("0");
		}
	}
	
	/**
	 * 判断nodeId的节点是否又子节点
	 * @param nodeId
	 * @return
	 */
	public boolean hasChildren(String nodeId,Class clazz) {
		// TODO Auto-generated method stub
		//TreeBasePojo treeNode = (TreeBasePojo)this.baseDAO.get(clazz, nodeId);
		TreeBasePojo treeNodeTemp = new TreeBasePojo();

		DetachedCriteria criteria = DetachedCriteria
				.forClass(clazz)
				.add(Restrictions.eq(this.PARENT_ID,nodeId))
				.setProjection(Projections.count(this.UNIQUE_CODE));
		
		Integer i= (Integer)this.baseDAO.findByCriteria(criteria).get(0);
		
		if(i==0){
			return false;
		}else{
			return true;
		}
		
	}	
	/**
	 * 获得节点ID为nodeId的节点的子集的serialNumber的最大数字
	 * @param	nodeId	节点id
	 */
	public int getMaxSerialNumber(String nodeId,Class clazz){
		DetachedCriteria criteria = DetachedCriteria
				.forClass(clazz)
				.add(Restrictions.eq(this.PARENT_ID,nodeId))
				.setProjection(Projections.max(this.SERIAL_NUMBER));
		
		List<Object> list=this.baseDAO.findByCriteria(criteria);
		
		int num=0;
		
		if(!list.isEmpty()&&list.get(0)!=null){
			num = Integer.valueOf(list.get(0).toString());
		}
		
		return num;
	}
	
}
